package io.renren.modules.reception.controller;

import java.util.*;
import java.util.concurrent.TimeUnit;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.additional.query.impl.LambdaQueryChainWrapper;
import io.renren.common.annotation.NoRepeatSubmit;
import io.renren.common.utils.FastIDUtil;
import io.renren.common.utils.RedisUtils;
import io.renren.modules.constants.RedisConstants;
import io.renren.modules.reception.entity.vo.*;
import io.renren.modules.reception.init.TableThemeCache;
import io.renren.modules.store.entity.TStoreDiningTableEntity;
import io.renren.modules.store.entity.TTableThemeEntity;
import io.renren.modules.store.service.TStoreDiningTableService;
import io.renren.modules.store.service.TTableThemeService;
import io.renren.modules.sys.controller.AbstractController;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import io.renren.modules.reception.entity.TStoreOpenDeskEntity;
import io.renren.modules.reception.service.TStoreOpenDeskService;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.R;



/**
 * 
 *
 * @author steakliu
 * @email 2319492349@qq.com
 * @date 2021-02-01 20:55:39
 */
@RestController
@RequestMapping("reception/tstoreopendesk")
public class TStoreOpenDeskController extends AbstractController {
    @Autowired
    private TStoreOpenDeskService tStoreOpenDeskService;
    @Autowired
    private TStoreDiningTableService diningTableService;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    private TTableThemeService tableThemeService;

    /**
     * 列表
     */
    @RequestMapping("/list")
    @RequiresPermissions("reception:tstoreopendesk:list")
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = tStoreOpenDeskService.queryPage(params);

        return R.ok().put("page", page);
    }

    /**
     * 预接
     */
    @NoRepeatSubmit
    @RequestMapping("/preCheck")
    public R preCheck(@RequestBody OpenDeskVo openDeskVo){
        Map<String, Object> map = BeanUtil.beanToMap(openDeskVo.getOrderInfo());
        redisTemplate.opsForHash().putAll(RedisConstants.OPEN_DESK_PREFIX+openDeskVo.getOrderInfo().getId() +RedisConstants.OPEN_DESK_SYMBOL+getSeller(),map);

        //更新餐台
        TStoreDiningTableEntity diningTableEntity = new TStoreDiningTableEntity();
        diningTableEntity.setId(openDeskVo.getOrderInfo().getId());
        diningTableEntity.setStyle(TableThemeCache.get(getSeller()).getPreColor());
        diningTableEntity.setStatus(5);
        diningTableEntity.setMoney(openDeskVo.getOrderInfo().getTotalMoney());
        diningTableService.updateById(diningTableEntity);
        return R.ok();
    }

    /**
     * 信息
     */
    @RequestMapping("/info/{orderId}")
    @RequiresPermissions("reception:tstoreopendesk:info")

    public R info(@PathVariable("orderId") Long orderId){
		TStoreOpenDeskEntity tStoreOpenDesk = tStoreOpenDeskService.getById(orderId);

        return R.ok().put("tStoreOpenDesk", tStoreOpenDesk);
    }

    /**
     * 整单转菜
     */
    @PostMapping("allOrderTransfe")
    @Transactional(rollbackFor = Exception.class)
    public R allOrderTransfe(@RequestBody TransfeVo orderInfos){
        for (OrderInfo orderInfo : orderInfos.getOrderInfos()){
            redisTemplate.opsForHash().put(RedisConstants.OPEN_DESK_PREFIX+orderInfo.getId() +RedisConstants.OPEN_DESK_SYMBOL+getSeller(),"totalMoney",orderInfo.getTotalMoney());
            redisTemplate.opsForHash().put(RedisConstants.OPEN_DESK_PREFIX+orderInfo.getId() +RedisConstants.OPEN_DESK_SYMBOL+getSeller(),"foodVos",orderInfo.getFoodVos());
        }
        return R.ok();
    }

    /**
     * 合并餐台
     */
    @PostMapping("mergeDesk")
    @Transactional(rollbackFor = Exception.class)
    public R mergeDesk(@RequestBody MergeDeskVo mergeDeskVo){
        TStoreDiningTableEntity diningTableEntity = new TStoreDiningTableEntity();
        diningTableEntity.setId(mergeDeskVo.getOrderInfo().getId());
        diningTableEntity.setMaster(1);
        boolean b = diningTableService.updateById(diningTableEntity);

        List<TStoreDiningTableEntity> list = new ArrayList<>();
        for (int i = 0 ; i < mergeDeskVo.getTargetDeskList().size() ; i++){
            TStoreDiningTableEntity diningTableEntity1 = new TStoreDiningTableEntity();
            diningTableEntity1.setId(mergeDeskVo.getTargetDeskList().get(i));
            diningTableEntity1.setSlave(1);
            diningTableEntity1.setMasterId(mergeDeskVo.getOrderInfo().getId());
            list.add(diningTableEntity1);
        }
        diningTableService.updateBatchById(list);
        return R.ok();

    }

    /**
     * 拆分餐台
     */
    @GetMapping("splitDesk")
    @Transactional(rollbackFor = Exception.class)
    public R splitDesk(@RequestParam Long deskId , @RequestParam Long masterId){
        Map<String,Object> map = new HashMap<>();
        map.put("sellerId",getSeller());
        map.put("deskId",deskId);
        if (masterId == 0){
            diningTableService.splitDesk(map);
        }else {
            TStoreDiningTableEntity entity = diningTableService.getById(deskId);
            boolean update = diningTableService.update(new UpdateWrapper<TStoreDiningTableEntity>()
                    .set("master", 0)
                    .set("slave", 0)
                    .set("master_id", 0)
                    .eq("seller_id", map.get("sellerId"))
                    .eq("master_id", entity.getMasterId())
                    .or()
                    .eq("id", entity.getMasterId())
            );
        }
        return R.ok();
    }

    /**
     * 整单复制
     */
    @PostMapping("copyOrder")
    @Transactional(rollbackFor = Exception.class)
    public R copyOrder(@RequestBody CopyOrderVo copyOrderVo){
        List<OrderInfo> orderVoList = new ArrayList<>();
        List<TStoreDiningTableEntity> diningTableEntityList = new ArrayList<>();
        for (int i = 0 ; i < copyOrderVo.getTargetDeskList().size() ; i++){
            TStoreDiningTableEntity one = diningTableService.getOne(new QueryWrapper<TStoreDiningTableEntity>()
                    .eq("dining_table_no", copyOrderVo.getTargetDeskList().get(i))
                    .eq("seller_id", getSeller())

            );
            OrderInfo copy = new OrderInfo();
            BeanUtil.copyProperties(copyOrderVo.getOrderInfo(),copy);
            copy.setId(one.getId());
            copy.setDiningTableNo(copyOrderVo.getTargetDeskList().get(i));
            copy.setOrderId(FastIDUtil.fastId());
            copy.setOpenTime(new Date());
            copy.setTotalMoney(copyOrderVo.getOrderInfo().getTotalMoney());
            orderVoList.add(copy);

            //改变餐桌状态
            TStoreDiningTableEntity diningTableEntity = new TStoreDiningTableEntity();
            diningTableEntity.setStyle(TableThemeCache.get(getSeller()).getEatColor());
            diningTableEntity.setId(one.getId());
            diningTableEntity.setStatus(2);
            diningTableEntity.setTime(new Date());
            diningTableEntity.setMoney(copyOrderVo.getOrderInfo().getTotalMoney());
            diningTableEntityList.add(diningTableEntity);
        }

        //存入缓存
        for (OrderInfo orderInfo : orderVoList) {
            Map<String, Object> map = BeanUtil.beanToMap(orderInfo);
            redisTemplate.opsForHash().putAll(RedisConstants.OPEN_DESK_PREFIX + orderInfo.getId() +RedisConstants.OPEN_DESK_SYMBOL+getSeller(), map);
        }
        //改变餐桌状态
        diningTableService.updateBatchById(diningTableEntityList);

        return R.ok();
    }



    /**
     * 转台
     */
    @PutMapping("/turnDesk")
    @Transactional(rollbackFor = Exception.class)
    public R turnDesk(@RequestParam("sourceDesk") Long sourceDesk,
                      @RequestParam("targetDesk") Long targetDesk,
                      @RequestParam("diningTableNo") String diningTableNo,
                      @RequestParam("master") Integer master,
                      @RequestParam("slave") Integer slave,
                      @RequestParam("masterId") Long masterId,
                      @RequestParam("money") Double money,
                      @RequestParam("time") String time,
                      @RequestParam("style") String style,
                      @RequestParam("status") Integer status){
        //更改餐桌状态
        List<TStoreDiningTableEntity> list = new ArrayList<>();
        TStoreDiningTableEntity sourceTableEntity = new TStoreDiningTableEntity();
        TStoreDiningTableEntity targetTableEntity = new TStoreDiningTableEntity();
        sourceTableEntity.setId(sourceDesk);
        sourceTableEntity.setStatus(1);
        sourceTableEntity.setMasterId(0L);
        sourceTableEntity.setMaster(0);
        sourceTableEntity.setSlave(0);
        sourceTableEntity.setMoney(0.0);
        sourceTableEntity.setTime(DateUtil.parseDateTime(time));
        sourceTableEntity.setMoney(money);
        sourceTableEntity.setStyle(TableThemeCache.get(getSeller()).getFreeColor());

        targetTableEntity.setId(targetDesk);
        targetTableEntity.setStatus(status);
        targetTableEntity.setMoney(money);
        targetTableEntity.setTime(DateUtil.parseDateTime(time));
        if (master == 1){
            targetTableEntity.setMasterId(0L);
            targetTableEntity.setSlave(0);
            targetTableEntity.setMaster(1);
        }else if (slave == 1){
            targetTableEntity.setMasterId(masterId);
            targetTableEntity.setSlave(1);
            targetTableEntity.setMaster(0);
        }else {
            targetTableEntity.setMasterId(0L);
            targetTableEntity.setSlave(0);
            targetTableEntity.setMaster(0);
        }

        targetTableEntity.setStyle(style);

        list.add(sourceTableEntity);
        list.add(targetTableEntity);
        diningTableService.updateBatchById(list);

        diningTableService.update(new UpdateWrapper<TStoreDiningTableEntity>()
                .set("master_id", targetDesk)
                .eq("master_id", sourceDesk)
                .eq("seller_id", getSeller())
        );

        //更改缓存信息
        redisTemplate.opsForHash().put(RedisConstants.OPEN_DESK_PREFIX+sourceDesk +RedisConstants.OPEN_DESK_SYMBOL+getSeller(),"id",targetDesk);
        redisTemplate.opsForHash().put(RedisConstants.OPEN_DESK_PREFIX+sourceDesk +RedisConstants.OPEN_DESK_SYMBOL+getSeller(),"diningTableNo",diningTableNo);
        Map<Object, Object> entries = redisTemplate.opsForHash().entries(RedisConstants.OPEN_DESK_PREFIX + sourceDesk +RedisConstants.OPEN_DESK_SYMBOL+ getSeller());
        redisTemplate.opsForHash().putAll(RedisConstants.OPEN_DESK_PREFIX+targetDesk +RedisConstants.OPEN_DESK_SYMBOL+getSeller(),entries);
        redisTemplate.delete(RedisConstants.OPEN_DESK_PREFIX+sourceDesk +RedisConstants.OPEN_DESK_SYMBOL+getSeller());
        return R.ok();
    }

    /**
     * 清台
     */
    @RequestMapping("/clearDesk/{id}")
    @Transactional(rollbackFor = Exception.class)
    public R clearDesk(@PathVariable("id") Long id ){
        TStoreDiningTableEntity diningTableEntity = new TStoreDiningTableEntity();
        diningTableEntity.setStatus(1);
        diningTableEntity.setStyle(TableThemeCache.get(getSeller()).getFreeColor());
        diningTableEntity.setId(id);
        diningTableService.updateById(diningTableEntity);

        boolean b = tStoreOpenDeskService.remove(new QueryWrapper<TStoreOpenDeskEntity>()
                .eq("desk_id", id)
        );
        return R.ok();
    }

    /**
     * 清台
     */
    @RequestMapping("/clearAllDesk")
    @Transactional(rollbackFor = Exception.class)
    public R clearAllDesk(){
        boolean update = diningTableService.update(new UpdateWrapper<TStoreDiningTableEntity>()
                .eq("seller_id", getSeller())
                .eq("status", 3)
                .set("status", 1)
                .set("style", TableThemeCache.get(getSeller()).getFreeColor())
        );
        return R.ok();
    }

    /**
     * 保存
     */
    @NoRepeatSubmit
    @RequestMapping("/save")
//    @RequiresPermissions("reception:tstoreopendesk:save")
    @Transactional(rollbackFor = Exception.class)
    public R save(@RequestBody TStoreOpenDeskEntity tStoreOpenDesk){
        //改变餐台状态
        TStoreDiningTableEntity diningTableEntity = new TStoreDiningTableEntity();
        diningTableEntity.setStatus(2);
        TTableThemeEntity one = tableThemeService.getOne(
                new LambdaQueryWrapper<TTableThemeEntity>()
                        .eq(TTableThemeEntity::getSellerId, getSeller())
        );
        diningTableEntity.setStyle(one.getEatColor());
        diningTableEntity.setId(tStoreOpenDesk.getDeskId());
        diningTableEntity.setMoney(0.0);
        diningTableEntity.setTime(new Date());
        diningTableService.updateById(diningTableEntity);

        TStoreDiningTableEntity tableEntity = diningTableService.getById(tStoreOpenDesk.getDeskId());

        //存入redis
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setOpenTime(tStoreOpenDesk.getOpenTime());
        orderInfo.setId(tStoreOpenDesk.getDeskId());
        orderInfo.setDiningTableNo(tableEntity.getDiningTableNo());
        orderInfo.setEatNumer(tStoreOpenDesk.getPeopleNum());
        orderInfo.setStaffName(tStoreOpenDesk.getStaffName());
        orderInfo.setDeskAnotherName(tStoreOpenDesk.getDeskAnotherName());
        orderInfo.setOpenDeskRemark(tStoreOpenDesk.getOpenDeskRemark());
        orderInfo.setOrderId(FastIDUtil.fastId());
        orderInfo.setDiscountMoney(0.0);
        orderInfo.setOpenTime(new Date());
        Map<String, Object> map = BeanUtil.beanToMap(orderInfo);
        redisTemplate.opsForHash().putAll(RedisConstants.OPEN_DESK_PREFIX+orderInfo.getId() +RedisConstants.OPEN_DESK_SYMBOL+getSeller(),map);

        return R.ok().put("openDeskInfo",orderInfo);
    }

    //修改餐台
    @RequestMapping("/updateDesk")
    public R updateDesk(@RequestBody TStoreOpenDeskEntity tStoreOpenDeskEntity){
        redisTemplate.opsForHash().put(RedisConstants.OPEN_DESK_PREFIX+tStoreOpenDeskEntity.getDeskId() +RedisConstants.OPEN_DESK_SYMBOL+getSeller(),
                "eatNumer",tStoreOpenDeskEntity.getPeopleNum());
        redisTemplate.opsForHash().put(RedisConstants.OPEN_DESK_PREFIX+tStoreOpenDeskEntity.getDeskId() +RedisConstants.OPEN_DESK_SYMBOL+getSeller(),"deskAnotherName",tStoreOpenDeskEntity.getDeskAnotherName());
        redisTemplate.opsForHash().put(RedisConstants.OPEN_DESK_PREFIX+tStoreOpenDeskEntity.getDeskId() +RedisConstants.OPEN_DESK_SYMBOL+getSeller(), "openDeskRemark",tStoreOpenDeskEntity.getOpenDeskRemark());
        redisTemplate.opsForHash().put(RedisConstants.OPEN_DESK_PREFIX+tStoreOpenDeskEntity.getDeskId() +RedisConstants.OPEN_DESK_SYMBOL+getSeller(),"staffName",tStoreOpenDeskEntity.getStaffName());
        return R.ok();
    }

    /**
     * 下单
     */
    @RequestMapping("/xiadan")
    @Transactional(rollbackFor = Exception.class)
    public R xiadan(@RequestBody OpenDeskVo openDeskVo){
        //更改菜品集合和总价
        redisTemplate.opsForHash().put(RedisConstants.OPEN_DESK_PREFIX+openDeskVo.getOrderInfo().getId() +RedisConstants.OPEN_DESK_SYMBOL+getSeller(),
                "foodVos",openDeskVo.getOrderInfo().getFoodVos());
        redisTemplate.opsForHash().put(RedisConstants.OPEN_DESK_PREFIX+openDeskVo.getOrderInfo().getId() +RedisConstants.OPEN_DESK_SYMBOL+getSeller(),
                "totalMoney",openDeskVo.getOrderInfo().getTotalMoney());

        TStoreDiningTableEntity diningTableEntity = new TStoreDiningTableEntity();
        diningTableEntity.setId(openDeskVo.getOrderInfo().getId());
        diningTableEntity.setMoney(openDeskVo.getOrderInfo().getTotalMoney());
        diningTableService.updateById(diningTableEntity);
        return R.ok();
    }

    /**
     *合并订单信息
     */
    @RequestMapping("/queryMergeOrderInfo")
    public R queryMergeOrderInfo(@RequestParam Long deskId,@RequestParam Long masterId){
        List<Map<Object,Object>> mapList = new ArrayList<>();
        List<TStoreDiningTableEntity> list = null;
        if (masterId == 0){
            list = diningTableService.list(new QueryWrapper<TStoreDiningTableEntity>()
                    .eq("seller_id", getSeller())
                    .eq("master_id", deskId)
                    .or()
                    .eq("id", deskId)
            );
        }else {
            TStoreDiningTableEntity entity = diningTableService.getById(deskId);
            list = diningTableService.list(new QueryWrapper<TStoreDiningTableEntity>()
                    .eq("seller_id", getSeller())
                    .eq("master_id", entity.getMasterId())
                    .or()
                    .eq("id", entity.getMasterId())
            );
        }

        for (int i = 0 ; i < list.size() ; i++){
            Map<Object, Object> entries = redisTemplate.opsForHash().entries(RedisConstants.OPEN_DESK_PREFIX + list.get(i).getId() +RedisConstants.OPEN_DESK_SYMBOL+ getSeller());
            mapList.add(entries);
        }
        return R.ok().put("mergeOrderInfo",mapList);
    }


    /**
     *
     */
    @RequestMapping("/queryOrderInfo/{id}")
    public R queryOrderInfo(@PathVariable("id") Long id){
        Map<Object, Object> entries = redisTemplate.opsForHash().entries(RedisConstants.OPEN_DESK_PREFIX + id +RedisConstants.OPEN_DESK_SYMBOL+ getSeller());
        return R.ok().put("openDeskInfo",entries);
    }

    @RequestMapping("/queryOrderInfoById")
    public R queryOrderInfo(@RequestParam("idList") List<Long> idList){
        List<Map<Object,Object>> list = new ArrayList<>();
        for(Long id : idList) {
            Map<Object, Object> entries = redisTemplate.opsForHash().entries(RedisConstants.OPEN_DESK_PREFIX + id +RedisConstants.OPEN_DESK_SYMBOL+ getSeller());
            list.add(entries);
        }
        return R.ok().put("orderInfoList",list);
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    @RequiresPermissions("reception:tstoreopendesk:update")
    public R update(@RequestBody TStoreOpenDeskEntity tStoreOpenDesk){
		tStoreOpenDeskService.updateById(tStoreOpenDesk);

        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    @RequiresPermissions("reception:tstoreopendesk:delete")
    public R delete(@RequestBody Long[] orderIds){
		tStoreOpenDeskService.removeByIds(Arrays.asList(orderIds));

        return R.ok();
    }

}
